package com.atguigu.tingshu.user.service.impl;

import java.util.*;

import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.mapper.UserVipServiceMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.service.UserPaidTrackService;
import com.atguigu.tingshu.user.service.VipServiceConfigService;
import com.atguigu.tingshu.user.strategy.ProcessPaidRecord;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.google.common.collect.Maps;

import com.atguigu.tingshu.user.mapper.UserPaidAlbumMapper;
import com.atguigu.tingshu.user.service.MqOpsService;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

/**
 * @author codingyz
 * @Description
 * @date 2025/3/30 14:08
 * @Version 1.0
 */
@Service
@Slf4j
public class MqOpsServiceImpl implements MqOpsService {

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
    private UserPaidTrackService userPaidTrackService;

    @Autowired
    private UserVipServiceMapper userVipServiceMapper;

    @Autowired
    private VipServiceConfigService vipServiceConfigService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    Map<String, ProcessPaidRecord> diffItemTypeMap; // spring容器会为每个实现类自动注入到容器中 key就是实现类的beanName

    public MqOpsServiceImpl(UserPaidAlbumMapper userPaidAlbumMapper, @Qualifier("com.atguigu.tingshu.album.client.AlbumInfoFeignClient") AlbumInfoFeignClient albumInfoFeignClient) {
        this.userPaidAlbumMapper = userPaidAlbumMapper;
        this.albumInfoFeignClient = albumInfoFeignClient;
    }

    @Override
    public void userPaidRecord(UserPaidRecordVo userPaidRecordVo) {
        String itemType = userPaidRecordVo.getItemType();
        // 1. 根据itemType判断购买的类型 "1001-专辑" "1002-声音" "1003-vip"
//        switch (itemType) {
//            case "1001":
//                dealItemTypeAlbumPaidRecord(userId, orderNo, itemIdList);
//                break;
//            case "1002":
//                dealItemTypeTrackPaidRecord(userId, orderNo, itemIdList);
//                break;
//            case "1003":
//                dealItemTypeVipPaidRecord(userId, orderNo, itemIdList);
//                break;
//        }
        // todo 适配器模式
        diffItemTypeMap.get(itemType).processDiffItemTypePaidRecord(userPaidRecordVo);
    }

    private void dealItemTypeAlbumPaidRecord(Long userId, String orderNo, List<Long> itemIdList) {
        // 1. 幂等性校验
        Long count = userPaidAlbumMapper.selectCount(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getOrderNo, orderNo).eq(UserPaidAlbum::getUserId, userId));
        if (count == 0) {
            // 已经存过了，直接返回
            log.error("该专辑订单流水已经记录");
            return;
        }
        // 2. 保存订单流水
        UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
        userPaidAlbum.setOrderNo(orderNo);
        userPaidAlbum.setUserId(userId);
        userPaidAlbum.setAlbumId(itemIdList.get(0));
        int insert = userPaidAlbumMapper.insert(userPaidAlbum);
        log.info("保存专辑订单流水{}", insert == 0 ? "失败" : "成功");
    }

    private void dealItemTypeTrackPaidRecord(Long userId, String orderNo, List<Long> itemIdList) {
        // 1. 幂等性校验
        long count = userPaidTrackService.count(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getOrderNo, orderNo).eq(UserPaidTrack::getUserId, userId));
        if (count == 0) {
            // 已经存过了，直接返回
            log.error("该声音订单流水已经记录");
            return;
        }
        // 2. 保存订单流水
        // 2.1 查询声音对应的专辑id
        Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlbumInfoByTrackId(itemIdList.get(0));
        AlbumInfo albumInfoResultData = albumInfoResult.getData();
        if (albumInfoResultData == null) {
            log.error("远程调用album_service获取专辑信息失败");
            throw new GuiguException(201, "远程调用album_service获取专辑信息失败");
        }
        List<UserPaidTrack> userPaidTracks = new ArrayList<>();
        for (Long trackId : itemIdList) {
            UserPaidTrack userPaidTrack = new UserPaidTrack();
            userPaidTrack.setOrderNo(orderNo);
            userPaidTrack.setUserId(userId);
            userPaidTrack.setAlbumId(0L);
            userPaidTrack.setTrackId(trackId);
            userPaidTracks.add(userPaidTrack);
        }
        boolean b = userPaidTrackService.saveBatch(userPaidTracks);
        log.info("保存声音订单流水{}", b ? "失败" : "成功");
    }

    private void dealItemTypeVipPaidRecord(Long userId, String orderNo, List<Long> itemIdList) {
        // 1. 幂等性校验
        Long count = userVipServiceMapper.selectCount(new LambdaQueryWrapper<UserVipService>().eq(UserVipService::getOrderNo, orderNo).eq(UserVipService::getUserId, userId));
        if (count == 0) {
            // 已经存过了，直接返回
            log.error("该声音订单流水已经记录");
            return;
        }
        // 2. 保存订单流水
        UserVipService userVipService = new UserVipService();
        userVipService.setOrderNo(orderNo);
        userVipService.setUserId(userId);
        userVipService.setVipConfigId(itemIdList.get(0).intValue());
        userVipService.setStartTime(new Date()); // 套餐开始时间 直接用当前时间
        // 查询该套餐的时长
        VipServiceConfig vipServiceConfig = vipServiceConfigService.getById(itemIdList.get(0));
        Integer serviceMonth = vipServiceConfig.getServiceMonth();// 套餐时长/月
        // 查询该用户是否vip还没过期
        UserInfoVo userInfoVo = userInfoService.getUserInfo(userId);
        Integer isVip = userInfoVo.getIsVip();
        Calendar calendar = Calendar.getInstance();// 日历对象 方便操作时间
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, serviceMonth);
        Date expireTime = calendar.getTime();
        if (isVip == 1 && userInfoVo.getVipExpireTime().after(new Date())) {
            // vip没过期
            calendar.setTime(userInfoVo.getVipExpireTime());
            calendar.add(Calendar.MONTH, serviceMonth);
            expireTime = calendar.getTime();
        }
        userVipService.setExpireTime(expireTime); // 需要判断 该用户是否vip还没过期 如果没过期 则是续费
        userVipServiceMapper.insert(userVipService);
        log.info("保存vip订单流水{}", "成功");
        // 3. 更新用户信息
        UserInfo userInfo = new UserInfo();
        userInfo.setIsVip(1);
        userInfo.setVipExpireTime(expireTime);
        boolean b = userInfoService.updateById(userInfo);
        log.info("更新用户vip信息{}", b ? "成功" : "失败");
    }
}
